package com.nulldev.util.java.swing;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.nulldev.util.FinalBypass;
import com.nulldev.util.io.FileUtil;
import com.nulldev.util.java.swing.extSwing.lookandfeel.themes.ThemeApplier;
import com.nulldev.util.string.StringsUtil;
import com.nulldev.util.threading.legacy.ThreadExecutor;
import com.nulldev.util.uri.nget.nGet;
import com.nulldev.util.uri.nget.nGetEvent;

import javax.swing.JProgressBar;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import java.awt.Toolkit;

public class nGetUI extends JFrame {

	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static nGetUI main(final nGet instance) {
		final FinalBypass<nGetUI> out = new FinalBypass<nGetUI>(null);
		ThreadExecutor.execute(new Runnable() {
			public void run() {
				try {
					nGetUI frame = new nGetUI(instance);
					frame.setVisible(true);
					ThemeApplier.applyTheme(frame);
					out.setObject(frame);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		while (!out.notNull()) {
			try {
				Thread.sleep(50L);
			} catch (InterruptedException e) {
			}
		}
		return out.getObject();
	}

	private final nGet get;
	
	/**
	 * Create the frame.
	 */
	protected nGetUI(final nGet get) {
		setIconImage(Toolkit.getDefaultToolkit().getImage(nGetUI.class.getResource("/com/nulldev/util/java/swing/nullutil_logo.png")));
		this.get = get;
		//setAlwaysOnTop(true);
		setResizable(false);
		setTitle("nGet: Downloading");
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(100, 100, 543, 275);
		
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);
		
		JMenuItem mntmAbout = new JMenuItem("About");
		mntmAbout.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				nullUtilAbout2.main();
			}
		});
		mnFile.add(mntmAbout);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		
		JProgressBar progressBar = new JProgressBar();
		progressBar.setStringPainted(true);
		//progressBar = (get == null ? progressBar : get.getBar());
		progressBar.setValue(0);
		contentPane.add(progressBar, BorderLayout.CENTER);
		
		JLabel lblDownloading = new JLabel("Downloading...");
		lblDownloading.setHorizontalAlignment(SwingConstants.CENTER);
		
		JLabel lblFileName = new JLabel("File Name:");
		
		JLabel lblDataDownloaded = new JLabel("Data Downloaded:");
		
		JLabel lblNa = new JLabel("N/A");
		
		JLabel lblB = new JLabel("0 B");
		
		JLabel lblFileProgress = new JLabel("Remaining:");
		
		JLabel lblB_1 = new JLabel("N/A");
		
		JLabel lblTimeRemaining = new JLabel("Time Remaining:");
		
		JLabel lblNa_1 = new JLabel("N/A");
		GroupLayout gl_contentPane = new GroupLayout(contentPane);
		gl_contentPane.setHorizontalGroup(
			gl_contentPane.createParallelGroup(Alignment.TRAILING)
				.addComponent(progressBar, GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE)
				.addComponent(lblDownloading, GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblFileName)
					.addPreferredGap(ComponentPlacement.RELATED, 347, Short.MAX_VALUE)
					.addComponent(lblNa)
					.addContainerGap())
				.addGroup(gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblDataDownloaded)
					.addPreferredGap(ComponentPlacement.RELATED, 291, Short.MAX_VALUE)
					.addComponent(lblB)
					.addContainerGap())
				.addGroup(gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblFileProgress)
					.addPreferredGap(ComponentPlacement.RELATED, 342, Short.MAX_VALUE)
					.addComponent(lblB_1)
					.addContainerGap())
				.addGroup(gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addComponent(lblTimeRemaining)
					.addPreferredGap(ComponentPlacement.RELATED, 305, Short.MAX_VALUE)
					.addComponent(lblNa_1)
					.addContainerGap())
		);
		gl_contentPane.setVerticalGroup(
			gl_contentPane.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addComponent(progressBar, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblDownloading)
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblFileName)
						.addComponent(lblNa))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblDataDownloaded)
						.addComponent(lblB))
					.addGap(18)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblFileProgress)
						.addComponent(lblB_1))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblTimeRemaining)
						.addComponent(lblNa_1))
					.addGap(37))
		);
		contentPane.setLayout(gl_contentPane);
		
		final nGetEvent nge = new nGetEvent() {
			
			private long length = -1;
			private boolean finished;
			
			@Override
			public void onStart(final long length) {
				progressBar.setMaximum((int) length);
				final String fn = getFileName();
				if (fn.length() > 32) {
					lblNa.setText(StringsUtil.limitChars(fn, 32)  + "...");
				}else {
					lblNa.setText(fn);
				}
				this.length = length;
			}
			
			@Override
			public void onFinish() {
				this.finished = true;
			}
			
			@Override
			public void onError() {
				this.finished = true;
			}
			
			private long prevBytes = -1;
			private long bytes;
			
			@Override
			public void onDownload(long bytes, double percent) {
				this.bytes = bytes;
				progressBar.setValue((int) bytes);
				lblB.setText(FileUtil.convertToStringRepresentation(bytes));
				lblB_1.setText(FileUtil.convertToStringRepresentation(length - bytes));
				
//				if (prevBytes > -1) {
//					final long diff = this.length - bytes;
//					final long diff_ = (diff / this.prevBytes) * 60;
//					//System.out.println(diff_);
//					lblNa_1.setText(MathUtil.formatSecondsL(diff_));
//				}
				this.prevBytes = bytes;
			}
		};
		get.registerEvent(nge);
	}
	
	public void end() {
		setVisible(false);
		dispose();
	}
	
	public nGet get() {
		return this.get;
	}
}
